{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.273323Z",
     "start_time": "2020-04-24T07:16:32.788645Z"
    }
   },
   "outputs": [],
   "source": [
    "import torch"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.291722Z",
     "start_time": "2020-04-24T07:16:33.275939Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18,\n",
       "        19, 20, 21, 22, 23, 24])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = torch.arange(1, 25)\n",
    "x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.306208Z",
     "start_time": "2020-04-24T07:16:33.294992Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(140451234973232,\n",
       " 140453303070664,\n",
       " 68811648,\n",
       " True,\n",
       " torch.Size([24]),\n",
       " torch.Size([24]),\n",
       " 24)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# TODO x.storage(): 为什么每次都在变动\n",
    "id(x), id(x.storage()), x.data_ptr(), x.is_contiguous(), x.shape, x.size(), x.numel()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# view (contiguous)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.324558Z",
     "start_time": "2020-04-24T07:16:33.310127Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[[ 1,  2,  3,  4],\n",
       "          [ 5,  6,  7,  8],\n",
       "          [ 9, 10, 11, 12]],\n",
       " \n",
       "         [[13, 14, 15, 16],\n",
       "          [17, 18, 19, 20],\n",
       "          [21, 22, 23, 24]]]),\n",
       " torch.Size([2, 3, 4]),\n",
       " 24)"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "view_0 = x.view(2, 3, 4)\n",
    "view_0, view_0.shape, view_0.numel()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.340087Z",
     "start_time": "2020-04-24T07:16:33.327483Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(140451234914240, 140453303267784, 68811648, True)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "id(view_0), id(view_0.storage()), view_0.data_ptr(), view_0.is_contiguous()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.355249Z",
     "start_time": "2020-04-24T07:16:33.342983Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([100,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,\n",
       "          15,  16,  17,  18,  19,  20,  21,  22,  23,  24]),\n",
       " tensor([[[100,   2,   3,   4],\n",
       "          [  5,   6,   7,   8],\n",
       "          [  9,  10,  11,  12]],\n",
       " \n",
       "         [[ 13,  14,  15,  16],\n",
       "          [ 17,  18,  19,  20],\n",
       "          [ 21,  22,  23,  24]]]))"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "view_0[0][0][0] = 100\n",
    "x, view_0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.372061Z",
     "start_time": "2020-04-24T07:16:33.358087Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([100,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,\n",
       "          15,  16,  17,  18,  19,  20,  21,  22,  23,  24]),\n",
       " 68811648,\n",
       " True,\n",
       " '-----------------------------------------------',\n",
       " tensor([100,   2,   3,   4,   5,   6,   7,   8,   9,  10,  11,  12,  13,  14,\n",
       "          15,  16,  17,  18,  19,  20,  21,  22,  23,  24]),\n",
       " 68811648,\n",
       " True)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "view_1 = view_0.view(view_0.numel())\n",
    "view_2 = view_0.view(-1) # equal view_1\n",
    "view_1, view_1.data_ptr(), view_1.is_contiguous(), \\\n",
    "'-----------------------------------------------', \\\n",
    "view_2, view_2.data_ptr(), view_2.is_contiguous()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.386881Z",
     "start_time": "2020-04-24T07:16:33.376392Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[100,   2,   3,   4,   5,   6],\n",
       "         [  7,   8,   9,  10,  11,  12],\n",
       "         [ 13,  14,  15,  16,  17,  18],\n",
       "         [ 19,  20,  21,  22,  23,  24]]),\n",
       " torch.Size([4, 6]),\n",
       " True,\n",
       " '------------------------------------------',\n",
       " tensor([[100,   7,  13,  19],\n",
       "         [  2,   8,  14,  20],\n",
       "         [  3,   9,  15,  21],\n",
       "         [  4,  10,  16,  22],\n",
       "         [  5,  11,  17,  23],\n",
       "         [  6,  12,  18,  24]]),\n",
       " torch.Size([6, 4]),\n",
       " False)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "view_3 = x.view(4, 6)\n",
    "view_4 = view_3.t()\n",
    "\n",
    "view_3, view_3.shape, view_3.is_contiguous(), \\\n",
    "'------------------------------------------', \\\n",
    "view_4, view_4.shape, view_4.is_contiguous()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.417370Z",
     "start_time": "2020-04-24T07:16:33.391270Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "view_4.view(2, 12) is not contigous\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(68811648, 68811648)"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "try:\n",
    "    view_4.view(2, 12)\n",
    "except:\n",
    "    print(\"view_4.view(2, 12) is not contigous\")\n",
    "    view_5 = view_4.view(2, 3, 4) # TODO why ok?\n",
    "    \n",
    "view_3.data_ptr(), view_5.data_ptr()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# reshpae (copy(robust, any tensor) or view )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.430672Z",
     "start_time": "2020-04-24T07:16:33.419982Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[100,   7,  13,  19],\n",
       "         [  2,   8,  14,  20],\n",
       "         [  3,   9,  15,  21],\n",
       "         [  4,  10,  16,  22],\n",
       "         [  5,  11,  17,  23],\n",
       "         [  6,  12,  18,  24]]),\n",
       " False,\n",
       " 68811648,\n",
       " '-----------------------------------------------',\n",
       " tensor([[101,   7,  13,  19,   2,   8,  14,  20,   3,   9,  15,  21],\n",
       "         [  4,  10,  16,  22,   5,  11,  17,  23,   6,  12,  18,  24]]),\n",
       " True,\n",
       " 68797696)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reshape_0 = view_4.reshape(2, 12) # copy robust, view_4 is not contiguous\n",
    "reshape_0[0][0] = 101\n",
    "\n",
    "view_4, view_4.is_contiguous(), view_4.data_ptr(), \\\n",
    "'-----------------------------------------------', \\\n",
    "reshape_0, reshape_0.is_contiguous(), reshape_0.data_ptr()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.444074Z",
     "start_time": "2020-04-24T07:16:33.432938Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[102,   2,   3,   4,   5,   6],\n",
       "         [  7,   8,   9,  10,  11,  12],\n",
       "         [ 13,  14,  15,  16,  17,  18],\n",
       "         [ 19,  20,  21,  22,  23,  24]]),\n",
       " True,\n",
       " 68811648,\n",
       " '-----------------------------------------------',\n",
       " tensor([[102,   2,   3,   4],\n",
       "         [  5,   6,   7,   8],\n",
       "         [  9,  10,  11,  12],\n",
       "         [ 13,  14,  15,  16],\n",
       "         [ 17,  18,  19,  20],\n",
       "         [ 21,  22,  23,  24]]),\n",
       " True,\n",
       " 68811648)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reshape_1 = view_3.reshape(6, 4) # view3 is contigous\n",
    "reshape_1[0][0] = 102\n",
    "view_3, view_3.is_contiguous(), view_3.data_ptr(), \\\n",
    "'-----------------------------------------------', \\\n",
    "reshape_1, reshape_1.is_contiguous(), reshape_1.data_ptr()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.455178Z",
     "start_time": "2020-04-24T07:16:33.446336Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[102,   2,   3,   4],\n",
       "         [  5,   6,   7,   8],\n",
       "         [  9,  10,  11,  12],\n",
       "         [ 13,  14,  15,  16],\n",
       "         [ 17,  18,  19,  20],\n",
       "         [ 21,  22,  23,  24]]),\n",
       " 68811648,\n",
       " '-----------------------------',\n",
       " tensor([[103,   2,   3,   4],\n",
       "         [  5,   6,   7,   8],\n",
       "         [  9,  10,  11,  12],\n",
       "         [ 13,  14,  15,  16],\n",
       "         [ 17,  18,  19,  20],\n",
       "         [ 21,  22,  23,  24]]),\n",
       " 68782272)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reshape_2 = reshape_1.clone() # clone\n",
    "reshape_2[0][0] = 103\n",
    "reshape_1, reshape_1.data_ptr(), \\\n",
    "'-----------------------------', \\\n",
    "reshape_2, reshape_2.data_ptr()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.466138Z",
     "start_time": "2020-04-24T07:16:33.457287Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[101,   7,  13,  19,   2,   8,  14,  20,   3,   9,  15,  21],\n",
       "         [  4,  10,  16,  22,   5,  11,  17,  23,   6,  12,  18,  24]]),\n",
       " 68797696,\n",
       " '-----------------------------',\n",
       " tensor([101,   7,  13,  19,   2,   8,  14,  20,   3,   9,  15,  21,   4,  10,\n",
       "          16,  22,   5,  11,  17,  23,   6,  12,  18,  24]),\n",
       " 68797696)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "reshape_3 = reshape_0.reshape(-1)\n",
    "reshape_0, reshape_0.data_ptr(), \\\n",
    "'-----------------------------', \\\n",
    "reshape_3, reshape_3.data_ptr()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## transpose (only swap two dimension, memory not contiguous, view)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.480508Z",
     "start_time": "2020-04-24T07:16:33.468490Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[101,   7,  13,  19,   2,   8,  14,  20,   3,   9,  15,  21],\n",
       "         [  4,  10,  16,  22,   5,  11,  17,  23,   6,  12,  18,  24]]),\n",
       " torch.Size([2, 12]),\n",
       " 68797696,\n",
       " True,\n",
       " '-------------------------------------------------------------------------',\n",
       " tensor([[101,   4],\n",
       "         [  7,  10],\n",
       "         [ 13,  16],\n",
       "         [ 19,  22],\n",
       "         [  2,   5],\n",
       "         [  8,  11],\n",
       "         [ 14,  17],\n",
       "         [ 20,  23],\n",
       "         [  3,   6],\n",
       "         [  9,  12],\n",
       "         [ 15,  18],\n",
       "         [ 21,  24]]),\n",
       " tensor([[101,   4],\n",
       "         [  7,  10],\n",
       "         [ 13,  16],\n",
       "         [ 19,  22],\n",
       "         [  2,   5],\n",
       "         [  8,  11],\n",
       "         [ 14,  17],\n",
       "         [ 20,  23],\n",
       "         [  3,   6],\n",
       "         [  9,  12],\n",
       "         [ 15,  18],\n",
       "         [ 21,  24]]),\n",
       " torch.Size([12, 2]),\n",
       " 68797696,\n",
       " False)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "trans_0 = reshape_0.transpose(0, 1)\n",
    "trans_1 = reshape_0.transpose(1, 0) # equal trans_0\n",
    "reshape_0, reshape_0.shape, reshape_0.data_ptr(), reshape_0.is_contiguous(), \\\n",
    "'-------------------------------------------------------------------------', \\\n",
    "trans_0, trans_1, trans_0.shape, trans_0.data_ptr(), trans_0.is_contiguous()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.491218Z",
     "start_time": "2020-04-24T07:16:33.482984Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[[102,   2,   3,   4],\n",
       "          [  5,   6,   7,   8],\n",
       "          [  9,  10,  11,  12]],\n",
       " \n",
       "         [[ 13,  14,  15,  16],\n",
       "          [ 17,  18,  19,  20],\n",
       "          [ 21,  22,  23,  24]]]),\n",
       " torch.Size([2, 3, 4]),\n",
       " tensor([[[102,   5,   9],\n",
       "          [  2,   6,  10],\n",
       "          [  3,   7,  11],\n",
       "          [  4,   8,  12]],\n",
       " \n",
       "         [[ 13,  17,  21],\n",
       "          [ 14,  18,  22],\n",
       "          [ 15,  19,  23],\n",
       "          [ 16,  20,  24]]]),\n",
       " torch.Size([2, 4, 3]))"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "trans_2 = view_0.transpose(1, 2)\n",
    "view_0, view_0.shape, \\\n",
    "trans_2, trans_2.shape, \\"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.505006Z",
     "start_time": "2020-04-24T07:16:33.493426Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[111,   7,  13,  19,   2,   8,  14,  20,   3,   9,  15,  21],\n",
       "         [  4,  10,  16,  22,   5,  11,  17,  23,   6,  12,  18,  24]]),\n",
       " True,\n",
       " '----------------------------------',\n",
       " tensor([[111,   4],\n",
       "         [  7,  10],\n",
       "         [ 13,  16],\n",
       "         [ 19,  22],\n",
       "         [  2,   5],\n",
       "         [  8,  11],\n",
       "         [ 14,  17],\n",
       "         [ 20,  23],\n",
       "         [  3,   6],\n",
       "         [  9,  12],\n",
       "         [ 15,  18],\n",
       "         [ 21,  24]]),\n",
       " False)"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "trans_0[0][0] = 111\n",
    "reshape_0, reshape_0.is_contiguous(), \\\n",
    "'----------------------------------', \\\n",
    "trans_0, trans_0.is_contiguous()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.515988Z",
     "start_time": "2020-04-24T07:16:33.507358Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(68750400, 68797696, True)"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "trans_1 = trans_0.contiguous()\n",
    "trans_1.data_ptr(), trans_0.data_ptr(), trans_1.is_contiguous()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## permute (swap all the dimensions)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.529716Z",
     "start_time": "2020-04-24T07:16:33.518128Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[111,   7,  13,  19,   2,   8,  14,  20,   3,   9,  15,  21],\n",
       "         [  4,  10,  16,  22,   5,  11,  17,  23,   6,  12,  18,  24]]),\n",
       " tensor([[111,   4],\n",
       "         [  7,  10],\n",
       "         [ 13,  16],\n",
       "         [ 19,  22],\n",
       "         [  2,   5],\n",
       "         [  8,  11],\n",
       "         [ 14,  17],\n",
       "         [ 20,  23],\n",
       "         [  3,   6],\n",
       "         [  9,  12],\n",
       "         [ 15,  18],\n",
       "         [ 21,  24]]),\n",
       " tensor([[111,   4],\n",
       "         [  7,  10],\n",
       "         [ 13,  16],\n",
       "         [ 19,  22],\n",
       "         [  2,   5],\n",
       "         [  8,  11],\n",
       "         [ 14,  17],\n",
       "         [ 20,  23],\n",
       "         [  3,   6],\n",
       "         [  9,  12],\n",
       "         [ 15,  18],\n",
       "         [ 21,  24]]))"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "permute_0 = reshape_0.permute(1, 0) # same transpose\n",
    "reshape_0, \\\n",
    "permute_0, trans_0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2020-04-24T07:16:33.540743Z",
     "start_time": "2020-04-24T07:16:33.531955Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([[[102,   2,   3,   4],\n",
       "          [  5,   6,   7,   8],\n",
       "          [  9,  10,  11,  12]],\n",
       " \n",
       "         [[ 13,  14,  15,  16],\n",
       "          [ 17,  18,  19,  20],\n",
       "          [ 21,  22,  23,  24]]]),\n",
       " torch.Size([2, 3, 4]),\n",
       " tensor([[[102,   5,   9],\n",
       "          [  2,   6,  10],\n",
       "          [  3,   7,  11],\n",
       "          [  4,   8,  12]],\n",
       " \n",
       "         [[ 13,  17,  21],\n",
       "          [ 14,  18,  22],\n",
       "          [ 15,  19,  23],\n",
       "          [ 16,  20,  24]]]),\n",
       " torch.Size([2, 4, 3]))"
      ]
     },
     "execution_count": 19,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "permute_1 = view_0.permute(0, 2, 1) # same transpose(1, 2)\n",
    "view_0, view_0.shape, \\\n",
    "permute_1, permute_1.shape"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# References\n",
    "\n",
    "[Difference between view, reshape, transpose and permute in PyTorch][1]\n",
    "\n",
    "[1]: (https://jdhao.github.io/2019/07/10/pytorch_view_reshape_transpose_permute/)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
